using System.Data;
using System.Data.SqlClient;
using System.Reflection;

namespace Sixeyed.CodeGeneration.Metadata.Database.Sources
{
    /// <summary>
    /// Metadata source for SQL Server databases
    /// </summary>
    public class SqlServerSource : DatabaseSource<SqlConnection, SqlCommand, SqlDataAdapter>
    {
        #region Overridden properties

        /// <summary>
        /// Gets the name of the source
        /// </summary>
        public override string Name
        {
            get { return "SqlServer Database"; }
        }

        /// <summary>
        /// Gets the description of the source
        /// </summary>
        public override string Description
        {
            get { return "To use SqlServer as a database metadata source"; }
        }

        /// <summary>
        /// Gets the SQL string to provide a list of stored procedures
        /// </summary>
        public override string StoredProcedureListSql
        {
            get { return "select ROUTINE_NAME from information_schema.routines where routine_type = 'PROCEDURE' order by ROUTINE_NAME"; }
        }

        /// <summary>
        /// Gets the SQL string to provide a list of database tables
        /// </summary>
        public override string TableListSql
        {
            get { return "SELECT name FROM sysobjects WHERE xtype = 'U'"; }
        }

        #endregion

        #region Overridden methods

        /// <summary>
        /// Gets the database command to return stored procedure metadata
        /// </summary>
        /// <param name="storedProcedureName">Name of stored procedure</param>
        /// <returns>Populated SqlCommand</returns>
        public override IDbCommand GetStoredProcedureCommand(string storedProcedureName)
        {
            SqlCommand command = this.CreateCommand(CommandType.StoredProcedure, storedProcedureName);
            MethodInfo info = typeof(SqlCommand).GetMethod("DeriveParameters", BindingFlags.NonPublic | BindingFlags.Instance);
            info.Invoke(command, new object[] { });
            return command;
        }

        /// <summary>
        /// Gets the database command to return table metadata
        /// </summary>
        /// <param name="tableName">Name of table</param>
        /// <returns>Populated SqlCommand</returns>
        public override IDbCommand GetTableCommand(string tableName)
        {
            SqlCommand command = this.CreateCommand(CommandType.Text, "SELECT * FROM {0}", tableName);
            return command;
        }

        #endregion
    }
}
